package com.miplus.ccrm.admin.service;

import com.miplus.ccrm.admin.utils.SpringContextUtil;
import com.miplus.ccrm.common.*;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

import static jdk.nashorn.internal.ir.debug.ObjectSizeCalculator.getObjectSize;

@Aspect
@Component
@Slf4j
public class RequestLoggingAspect {
    @Resource
    private JDataService jDataService;
    @Pointcut("execution(* com.miplus.ccrm.admin.controller.*.*(..))")
    public void loggableMethods(){

    }

    @Before("loggableMethods()")
    public void logReguest(JoinPoint joinPoint) {
        HttpServletRequest h=((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        log.info("{} {}.Recv:{}",
                JPubUtils.getReqIpAddr(h),
                joinPoint.getSignature().getName(),
                joinPoint.getArgs()
        );


        //2025-07-16 增加用户权限与API接口权限控制
        String premid= JUsrPerm.apiToPermission(joinPoint.getSignature().getName());
        if(JPubUtils.IsNotEmpty(premid)){
            String token= JPubUtils.getToken(h);
            String key = JPubUtils.getTokenKey(token);
            JSysUser user= (JSysUser)jDataService.get(key);
            if(!JUsrPerm.hasPermission(user,premid)){
                log.warn("user={} noPerm {} ",user.getUsrid(),premid);
                throw new ServiceException(EnumRCode.Forbidden.value, EnumRCode.Forbidden.name);
            }
        }

        h.setAttribute("request_ts",String.valueOf(System.currentTimeMillis()));
    }

    @AfterReturning(pointcut = "loggableMethods()",returning = "result")
    public void logResponse(JoinPoint joinPoint, Object result){
        HttpServletRequest h=((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String ln=(String) h.getAttribute("request_ts");
        log.info("{} {}.Resp:status={},size={},timeron={},{}",
                JPubUtils.getReqIpAddr(h),
                joinPoint.getSignature().getName(),
                ((R)result).getCode(),
                getObjectSize(result),
                JPubUtils.getTimeSpan(ln),
                result
        );
    }
}
